⓪ Notizen/Doku zum Compiler⓪ -------------------------⓪ ⓪ Autor: Thomas Tempelmann⓪ ⓪ Alias-Definitionen für Prozeduren 15.02.94⓪ ---------------------------------⓪ ⓪ Ziel: Es soll möglich sein, zu schreiben: CONST Wr = InOut.WriteString;⓪ ⓪ Während das in reinen Imp-Modulen kein Problem ist (es wird einfach durch⓪ einen Relay-Eintrag gelöst), sind solche Consts in Def-Modulen schwieriger.⓪ Zwar kann der Compiler auch dort automatisch solche Relays beim Importieren⓪ auflösen, aber dazu muß er auch das InOut-Modul importiert haben.⓪ ⓪ Bsp:⓪ Sei XP das Modul, das "Wr = InOut.WriteString" definiert. Modul IM importiert⓪ nun XP. Wenn XP vor IM auch InOut importiert, klappt alles, denn in XP.DEF⓪ steht der Key von InOut und so erkennt der Compiler, daß beide Module⓪ identisch sind und überträgt die Referenz von XP.Wr auf InOut.WriteString.⓪ Fehlt der InOut-Import, klappt dies nicht und der Compiler greift auf XP.Wr⓪ zu. So finden Loader/Linker aber das Item "WriteString" nicht, das aus InOut⓪ kommt, und kann daher auch gar nicht mit InOut relozieren.⓪ Das heißt: Beim beim Übersetzen von IM muß InOut vorhanden sein, damit XP.Wr⓪ auf InOut umgelenkt wird, so als ob InOut.WriteString benützt würde.⓪ ⓪ Das geht aber nur, wenn beim Import von XP automatisch InOut mit importiert⓪ wird. Dazu muß der Name von InOut im DEF-Modul v. XP stehen. Bisher werden⓪ aber nur die Keys, nicht die entsprechenden Modulnamen im DEF-Modul vermerkt.⓪ Das heißt, es muß eine zusätzliche Liste im Def-Modul erscheinen, die solch⓪ implizit zu importierenden Module aufführt, und zwar mitsamt ihres Keys zur⓪ Kontrolle.⓪ ⓪ Dazu wird das Modullayout bei Def-Modulen auf 6 erhöht und im Kopf ein⓪ Longs reserviert, der ggf. auf eine Liste der zu importierenden Module⓪ zeigt, die je aus einem Key und einem $FF-terminierten String bestehen.⓪ ⓪ Beim Übersetzen von IM geht der Import von XP folgendermaßen vor sich:⓪ Zuerst wird das Modul XP ganz normal ausgewertet: Das Image wird nach⓪ DADR geladen und dann der Header in den Import-Bereich vom Code (A4)⓪ kopiert, samt Namen, dann die Liste der importierten Items angefügt.⓪ ⓪ a) Übersetzen von Defmods:⓪ Während der Compiletime wird jedes Defmod mit seinem Namen, soweit bekannt,⓪ in der Importliste eingetragen, also auch beim Übersetzen von Def-Modulen⓪ (das ist neu seit V3.7). Werden dabei Items importiert, die aus einem anderen⓪ Modul stammen, wird in der neuen Impliziten Importliste nach dem Namen des⓪ Moduls gesucht und der Name mit in die Importliste übertragen (s. 'DefImp').⓪ Am Ende wird in NumImp ggf. eine neue Impliziten Importliste erzeugt.⓪ ⓪ b) Übersetzen von Impmods:⓪ s. IPIMP: Wird eine Proc/Var/Const importiert (die ja zu relozieren sind)⓪ und stammen die aus einem anderen Modul als dem gerade bearbeiteten, wird⓪ das Item in der Neubildliste mit gesetztem Bit 15 in der Kennung vermerkt.⓪ Am Ende, wenn alle Items importiert sind, wird in 'ImpXRef' die Implizite⓪ Importliste durchgegangen und für jedes dort aufgeführte Modul seine⓪ Neubildliste nach Kennungen mit gesetztem Bit 15 durchsucht. Kommen solche⓪ vor, wird der Modulname einfach in der Importliste des zu erzeugenden Impmods⓪ angefügt und dann jene Items dort eingetragen, so wie sie sonst in IPIMP⓪ an die aktuelle Importliste zu dem bearbeiteten Defmod angefügt worden wären.⓪ Der Rest ist wie immer.⓪ ⓪ Es ist noch eine kleine Macke drin. Bsp: Im Def-Mod "B"⓪ wird ein Alias aus A definiert. Def-Modul "C" importiert ihn aus "B" und⓪ definiert damit wiederum einen Alias, der von "D" importiert wird. Wird nun⓪ "D" gelinkt, kennt es "B" nicht automatisch sondern nur "C" (weil ausdrück-⓪ lich importiert und "A" (weil dort das Original des Alias herkommt). So⓪ wird dann "B" nicht mitgelinkt, es sei denn, "D" oder "C" importieren "B"⓪ im Implementationsteil.⓪ Auf diese "Macke" wird aber in der Praxis wohl niemand stoßen und wenn,⓪ dann kann es ja durch einen zusätzlichen Hilfsimport im Imp-Modul gelöst⓪ werden. Deshalb werde ich sie auch nicht beheben. Denn allein bis jetzt⓪ hat mich dieses winzige Feature 2 lange Tage beschäftigt und das soll⓪ reichen.⓪ ⓪ ⓪ Konstantenpuffer (DATA-Puffer) 23.12.93⓪ ------------------------------⓪ ⓪ Werden während der Übersetzung Konstanten erzeugt, die nicht im Baum⓪ liegen können (das sind anonyme, lokale und aus anderen zusammengesetzte),⓪ werden sie im DATA-Puffer abgelegt. Der ist wie folgt aufgebaut:⓪ ⓪"| Len.W der Daten (ggf. aufgerundet) | ^letzte Ref | Daten |⓪ ⓪ Der Ptr auf die "letzte Ref" ist eine Verkettung der Clienten dieser⓪ Konstante. Die Ptr sind absolut (nicht relativ zum Tree!). Das Ende wird⓪ durch NIL (0) gekennzeichnet.⓪ ⓪ Die Puffergröße wird durch "DataLen" vorgegeben (default: 20000, kann⓪ in OpenIO ggf. modifiziert werden). Der Puffer beginnt bei "DataStart"⓪ und muß vor "DataEnd" enden. Der akt. Zeiger auf den noch freien Bereich⓪ ist "DataPtr".⓪ ⓪ Am Ende der Compilierung müssen die benutzten Konstanten im Puffer alle⓪ direkt hintereinander gelegt ("Len" und "^letzte Ref" entfernen) und dabei⓪ gleichzeitig die Relozierliste entsprechend erweitert werden. Das geschieht⓪ in 2 Schritten: Zuerst werden die verwendeten Konsts. hinter den Code kopiert,⓪ danach werden die Relozierlisten erzeugt.⓪ Außerdem müssen noch die verwendeten Konst. im Tree in die Relozierliste⓪ aufgenommen und ihnen ein Platz im DATA-Segment zugewiesen werden.⓪ Zudem müssen die exportierten CONSTs in die entspr. Relozierliste aufgenommen⓪ werden.⓪ ⓪ Jede Konst. aus einer CONST-Anweisung wird auf jeden Fall im DATA abgelegt,⓪ wenn sie > "constBufsize" (z.Zt. 8) ist. Außerdem können sie in den DATA⓪ gelegt werden, wenn sie deref. werden (z.B. als REF-Parm).⓪ Achtung: Die CONSTs müssen beim Schließen ihres Trees in den DATA-Puffer⓪ kopiert werden, die ist v.A. bei lokalen CONSTs zu beachten, damit die⓪ Relozier-Info nicht verlorengeht. Das bedeutet dann, daß dann diese lokalen⓪ CONSTs nach Schließen ihres Scopes wie anonyme Konsts. im Puffer stehen.⓪ ⓪ Kommt eine Konstante in einer Expression vor, wird in "ExprDesc.varItem"⓪ der Verweis auf die CONST im Tree gespeichert bzw. NIL bei anonymen Konsts.⓪ Sobald entschieden ist, daß eine Konst. aus dem Tree in den DATA-Puffer⓪ gelegt werden soll, wird dies dadurch angezeigt, daß das Bit 4 in der⓪ Kennung gesetzt ist. Außerdem wird dann der "^letzte Ref" im Tree-Eintrag⓪ auf die Kette der Clienten zeigen, allerdings ggf. erst später bei der Code-⓪ Erzeugung, deshalb ist das Bit 4 für die Erkennung zu benutzen.⓪ ⓪ Bei anonymen und zusammengesetzten Konstanten, die nur für die Dauer der⓪ Expr-Auswertung existieren, ist "varItem" NIL.⓪ ⓪ Damit es keine Probleme mit String-Konstanten gibt, müssen diese immer⓪ 0-terminiert im DATA abgelegt werden!⓪ ⓪ Nur Konstanten mit "varItem" = NIL dürfen wie in Compiler V4.0-4.2 im DATA-⓪ Segment gekürzt, erweitert, verschoben und wieder gelöscht werden. Ist⓪ "varItem" nicht NIL, darf höchstens eine Selektion/Indizierung stattfinden,⓪ die über einen Offset zur Startadr. der Konstanten geschieht ("constOfs").⓪ Allerdings ist der Sonderfall zu beachten, daß durch eine Selektion/Indizierung⓪ einer CONST im DATA es dazu kommen kann, daß nun die Konst. wieder <= 8⓪ Byte ist und somit als "constant" direkt verarbeitet wird, anstatt sie⓪ über den DATA-Bereich weiterhin zu referenzieren.⓪ ⓪ EOF⓪ ⓪ ə